package logic;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Random;


public class ThreadGetchunk implements Runnable{
	private Server server;
	private String[] chunkParts;
	private boolean defautVersion;
	private InetAddress ip;
	public ThreadGetchunk(Server server,String[] chunkParts){
		this.server=server;
		this.chunkParts=chunkParts;
		this.defautVersion=true;


	}
	public ThreadGetchunk(Server server,String[] chunkParts, InetAddress ip){
		this.server=server;
		this.chunkParts=chunkParts;
		this.defautVersion=false;
		this.setIp(ip);


	}
	public void run(){


		byte[] sendData = new byte[65000];

		String fileID = chunkParts[2];
		int chunkNo= Integer.parseInt(chunkParts[3]);

		for(int i =0; i<Server.getChunkRepository().getChunks().size();i++)
		{
			Chunk chunk = Server.getChunkRepository().getChunks().elementAt(i);
			if(chunk.getFileID().equals(fileID) && chunk.getChunkNo()==chunkNo)
			{
				byte[] content = new byte[64000];
				int n=0;
				InputStream is = null;
				try{
					is = new FileInputStream(fileID+chunkNo);
					n=is.read(content);
					is.close();
				}catch(IOException e)
				{
					e.printStackTrace();
					break;
				}
				String reply=null;
				DatagramPacket sendPacket=null;
				DatagramPacket sendPacket2=null;
				if(this.defautVersion)
				{
					reply= new String("CHUNK "+Server.defautVersion+" "+fileID+" "+chunkNo+Server.CR+Server.LF+Server.CR+Server.LF);
					sendData=reply.getBytes();
					byte[] sendData2 = new byte[sendData.length+n];

					for(int j=0;j<sendData.length;j++)
					{

						sendData2[j]=new Byte(sendData[j]);

					}
					for(int j=0;j<n;j++)
					{

						sendData2[sendData.length+j]=new Byte(content[j]);

					}
					sendPacket = new DatagramPacket(sendData2, sendData2.length, server.getMDR_address(), server.getMDR_port());
					
				}
				else
				{
					reply= new String("CHUNK "+Server.defautVersion+" "+fileID+" "+chunkNo+Server.CR+Server.LF+Server.CR+Server.LF);
					sendData=reply.getBytes();
					sendPacket = new DatagramPacket(sendData, sendData.length, server.getMDR_address(), server.getMDR_port());
					
					reply= new String("CHUNK "+Server.VERSION+" "+fileID+" "+chunkNo+Server.CR+Server.LF+Server.CR+Server.LF);
					sendData=reply.getBytes();
					
					byte[] sendData2 = new byte[sendData.length+n];

					for(int j=0;j<sendData.length;j++)
					{

						sendData2[j]=new Byte(sendData[j]);

					}
					for(int j=0;j<n;j++)
					{

						sendData2[sendData.length+j]=new Byte(content[j]);

					}
					sendPacket2 = new DatagramPacket(sendData2, sendData2.length, ip, Integer.parseInt(chunkParts[4]));
					
				}
				Random randomGenerator = new Random();

				int random = randomGenerator.nextInt(Server.delay);
				long t= System.currentTimeMillis();
				long end = t+random;

				boolean send = true;
				while (System.currentTimeMillis() < end) {

					try {
						ChunkMessage ch = new ChunkMessage(fileID, chunkNo);
						if(server.getChunkMessage().contains(ch))
						{
							send=false;
							break;
						}

					} catch (Exception  e) {

						e.printStackTrace();
					}

				}

				try {
					if(send)
					{

						server.getMDR_socket().send(sendPacket);
						LogMensage lm=new LogMensage("SEND CHUNK FileID: "+fileID+ "Chunk number: "+chunkNo);

						Server.logMensagesStr.insertElementAt(lm.str(), 0);
						if(!defautVersion)
						{
							DatagramSocket clientSocket = new DatagramSocket();
							
							clientSocket.send(sendPacket2);
							lm=new LogMensage("SEND CHUNK to HOST: "+ip.getHostName()+" FileID: "+fileID+ "Chunk number: "+chunkNo);

							Server.logMensagesStr.insertElementAt(lm.str(), 0);
							clientSocket.close();
						}
					}

				} catch (IOException e) {
					e.printStackTrace();
				}

				/*fim de teste*/
			}
		}

	}
	public InetAddress getIp() {
		return ip;
	}
	public void setIp(InetAddress ip) {
		this.ip = ip;
	}

}
